﻿#include "FITKAbaqusAdaptorStepFrequency.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"
#include "FITK_Interface/FITKInterfaceModel/FITKAssInstanceTR.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceModel/FITKUnstructuredMesh.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMeshPartVTK.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaStepFrequency.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Kernel/FITKAppFramework/FITKMessage.h"

namespace IO
{
    QString FITKAbaqusAdaptorStepFrequency::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorStepStatic";
    }

    bool FITKAbaqusAdaptorStepFrequency::adaptR()
    {
        _stepData = dynamic_cast<Interface::FITKAbaStepFrequency*>(_dataObj);
        if (!_stepData || !_reader) return false;
        bool isRead = false;
        //读取静态分析的参数
        _reader->backLine();
        QString line = _reader->readLine();
        //校验
        if (!line.toLower().startsWith("*frequency")) return false;
        //关键字处理
        InpKeyLineSpliter s(line, _reader);

        //特征值求解器
        QString eigensolver = s["eigensolver"];
        QString sim = s["sim"];
        QString acousticCoupling = s["acoustic coupling"];
        //暂时还没有这个参数
        QString normalization = s["normalization"];
        if (eigensolver == "Lanczos")
        {
            isRead = readLanczos();
        }
        else if (eigensolver == "AMS")
        {
            isRead = readAMS();
        }
        else if (eigensolver == "subspace")
        {
            isRead = readSubspace();
        }
        //设置sim
        _stepData->setUseSIMBasedLinearDynamicProcedures(!(sim.size() == 2));

        if (acousticCoupling == "projection") //Project
        {
            _stepData->setAcousticStructuralCouplingWhereApplicableType(Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable::Project);
        }
        else if (acousticCoupling == "off") //exclude
        {
            _stepData->setAcousticStructuralCouplingWhereApplicableType(Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable::Exclude);
        }
        else if (acousticCoupling == "on") //Include
        {
            _stepData->setAcousticStructuralCouplingWhereApplicableType(Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable::Include);
        }

        if (normalization == "displacement")
        {
            _stepData->setNormalizeEnginevectors(Interface::FITKAbaAbstractStep::NormalizeEnginevectors::Displacement);
        }

        return isRead;
    }

    bool FITKAbaqusAdaptorStepFrequency::adaptW()
    {
        _stepData = dynamic_cast<Interface::FITKAbaStepFrequency*>(_dataObj);
        if (!_stepData || !_writer) return false;
        // 写出节点函数主体
        QTextStream* stream = _writer->getStream();
        bool isWrite = false;

        if (_stepData->getEigenSolver() == Interface::FITKAbaAbstractStep::Eigensolver::Lanczos)
        {
            isWrite = writeLanczos();
        }
        else if (_stepData->getEigenSolver() == Interface::FITKAbaAbstractStep::Eigensolver::AMS)
        {
            isWrite = writeAMS();
        }
        else if (_stepData->getEigenSolver() == Interface::FITKAbaAbstractStep::Eigensolver::Subspace)
        {
            isWrite = writeSubspace();
        }
        //sim
        titleLine.append(", sim");
        if (!_stepData->getUseSIMBasedLinearDynamicProcedures())
        {
            titleLine.append("=NO");
        }
        //AcousticCoupling
        auto acousticCoupling = _stepData->getAcousticStructuralCouplingWhereApplicableType();
        if (acousticCoupling == Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable::Project)
        {
            titleLine.append(", acoustic coupling=projection");
        }
        else if (acousticCoupling == Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable::Exclude) //exclude
        {
            titleLine.append(", acoustic coupling=off");
        }
        else if (acousticCoupling == Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable::Include)
        {
            titleLine.append(", acoustic coupling=on");
        }
        //Mass 可能不需要写出
        if (_stepData->getNormalizeEnginevectors() == Interface::FITKAbaAbstractStep::NormalizeEnginevectors::Displacement)
        {
            titleLine.append(", normalization=displacement");
        }


        if (isWrite)
        {
            *stream << titleLine << endl;
            *stream << valueLine << endl;
        }

        return isWrite;
    }

    bool FITKAbaqusAdaptorStepFrequency::readLanczos()
    {
        _stepData->setEigenSolver(Interface::FITKAbaAbstractStep::Eigensolver::Lanczos);
        QString line = _reader->previousLine();

        line = _reader->readLine();
        if (line.startsWith("*")) return false;
        auto sList = line.split(",");

        if (processingLengthAndIsNull(sList, 0))
        {
            int eigenvaluesRequested = sList[0].toInt();
            _stepData->setNumberOfEigenvaluesRequestedType(Interface::FITKAbaAbstractStep::NumberOfEigenvaluesRequsted::ValueNumberOfEigen);
            _stepData->setNumberOfEigenvaluesRequested(eigenvaluesRequested);
        }
        if (processingLengthAndIsNull(sList, 1))
        {
            double minFrequency = sList[1].toDouble();
            _stepData->setMinFreqIntrest(true);
            _stepData->setMinFreqInterstValue(minFrequency);
        }
        if (processingLengthAndIsNull(sList, 2))
        {
            double maxFrequency = sList[2].toDouble();
            _stepData->setMaxFrqInterst(true);
            _stepData->setMaxFreqInterstValue(maxFrequency);
        }
        if (processingLengthAndIsNull(sList, 3))
        {
            double ShiftValue = sList[3].toDouble();
            _stepData->setFrequencyShift(true);
            _stepData->setFrequencyShiftValue(ShiftValue);
        }
        if (processingLengthAndIsNull(sList, 4))
        {
            int blockSize = sList[4].toInt();
            _stepData->setBlockSizeType(Interface::FITKAbaAbstractStep::BlockSize::ValueBlock);
            _stepData->setBlockSizeValue(blockSize);
        }
        if (processingLengthAndIsNull(sList, 5))
        {
            int LanczosSteps = sList[5].toInt();
            _stepData->setMaximumNumberOfBlockLanczosStepType(Interface::FITKAbaAbstractStep::MaximumNumberOfBlockLanczosStep::ValueMaximum);
            _stepData->setMaxNumOfBlockLanczosSteps(LanczosSteps);
        }
        //暂时没发现第六个参数
        //if (processingLengthAndIsNull(sList,6))
        //{
        //    double AcousticRange = sList[6].toDouble();
        //    _stepData->setAcousticStructuralCouplingWhereApplicableType(Interface::AcousticStructuralCouplingWhereApplicable::Exclude);
        //    _stepData->setAcousticRangeFactor(AcousticRange);
        //}
        return true;
    }

    bool FITKAbaqusAdaptorStepFrequency::readAMS()
    {
        _stepData->setEigenSolver(Interface::FITKAbaAbstractStep::Eigensolver::AMS);
        QString line = _reader->previousLine();

        line = _reader->readLine();
        if (line.startsWith("*")) false;
        auto sList = line.split(",");

        if (processingLengthAndIsNull(sList, 0))
        {
            double eigenvaluesRequested = sList[0].toDouble();
            _stepData->setNumberOfEigenvaluesRequestedType(Interface::FITKAbaAbstractStep::NumberOfEigenvaluesRequsted::ValueNumberOfEigen);
            _stepData->setNumberOfEigenvaluesRequested(eigenvaluesRequested);
        }
        if (processingLengthAndIsNull(sList, 1))
        {
            double minFrequency = sList[1].toDouble();
            _stepData->setMinFreqIntrest(true);
            _stepData->setMinFreqInterstValue(minFrequency);
        }
        if (processingLengthAndIsNull(sList, 2))
        {
            double maxFrequency = sList[2].toDouble();
            _stepData->setMaxFrqInterst(true);
            _stepData->setMaxFreqInterstValue(maxFrequency);
        }
        if (processingLengthAndIsNull(sList, 3))
        {

        }
        if (processingLengthAndIsNull(sList, 4))
        {

        }
        if (processingLengthAndIsNull(sList, 5))
        {

        }
        if (processingLengthAndIsNull(sList, 6))
        {
            double AcousticRange = sList[6].toDouble();
            _stepData->setAcousticStructuralCouplingWhereApplicableType(Interface::FITKAbaAbstractStep::AcousticStructuralCouplingWhereApplicable::Exclude);
            _stepData->setAcousticRangeFactor(AcousticRange);
        }

        //读取后续行的残余模式
        while (!_reader->atEnd())
        {
            bool readOK = false;
            line = _reader->readLine();
            if (line.startsWith("*")) return true;

            auto sList = line.split(",");
            if (sList.size() != 2)return false;
            //标签
            QString label = sList[0];
            //第一自由度
            QString firstDegreeFreedom = sList[1];

            //数据结构中没找到设置位置
            return false;
        }
        return true;
    }

    bool FITKAbaqusAdaptorStepFrequency::readSubspace()
    {
        _stepData->setEigenSolver(Interface::FITKAbaAbstractStep::Eigensolver::Subspace);
        QString line = _reader->previousLine();


        line = _reader->readLine();
        if (line.startsWith("*")) false;
        auto sList = line.split(",");

        if (processingLengthAndIsNull(sList, 0))
        {
            double eigenvaluesRequested = sList[0].toDouble();
            _stepData->setNumberOfEigenvaluesRequestedType(Interface::FITKAbaAbstractStep::NumberOfEigenvaluesRequsted::ValueNumberOfEigen);
            _stepData->setNumberOfEigenvaluesRequested(eigenvaluesRequested);
        }
        if (processingLengthAndIsNull(sList, 1))
        {
            double maxFrequency = sList[1].toDouble();
            _stepData->setMaxFrqInterst(true);
            _stepData->setMaxFreqInterstValue(maxFrequency);
        }
        if (processingLengthAndIsNull(sList, 2))
        {
            double ShiftValue = sList[2].toDouble();
            _stepData->setFrequencyShift(true);
            _stepData->setFrequencyShiftValue(ShiftValue);
        }
        if (processingLengthAndIsNull(sList, 3))
        {
            double VectorsUsed = sList[3].toDouble();
            _stepData->setFrequencyShift(true);
            _stepData->setVectorsUsedPerIteration(VectorsUsed);
        }
        if (processingLengthAndIsNull(sList, 4))
        {
            double maxIteration = sList[4].toDouble();
            _stepData->setMaxNumberOfIteration(maxIteration);
        }
        return true;
    }

    bool FITKAbaqusAdaptorStepFrequency::writeLanczos()
    {
        //eigensolver
        titleLine.append("*Frequency, eigensolver=Lanczos");

        if (_stepData->getNumberOfEigenvaluesRequstedType() == Interface::FITKAbaAbstractStep::NumberOfEigenvaluesRequsted::ValueNumberOfEigen)
        {
            int eigenvalues = _stepData->getNumberOfEigenvaluesRequested();
            valueLine.append(QString::number(eigenvalues));
        }
        valueLine.append(", ");

        if (_stepData->getMinFreqIntrest())
        {
            double minFrequency = _stepData->getMinFreqInterstValue();
            valueLine.append(_writer->double2String(minFrequency, 8, 0));
        }
        valueLine.append(", ");

        if (_stepData->getMaxFreqInterst())
        {
            double maxFrequency = _stepData->getMaxFreqInterstValue();
            valueLine.append(_writer->double2String(maxFrequency, 8, 0));
        }
        valueLine.append(", ");

        if (_stepData->getFrequencyShift())
        {
            double ShiftValue = _stepData->getFrequencyShiftValue();
            valueLine.append(_writer->double2String(ShiftValue, 8, 0));
        }
        valueLine.append(", ");

        if (_stepData->getBlockSizeType() == Interface::FITKAbaAbstractStep::BlockSize::ValueBlock)
        {
            int blockSize = _stepData->getBlockSizeValue();
            valueLine.append(QString::number(blockSize));
        }
        valueLine.append(", ");

        if (_stepData->getMaximumNumberOfBlockLanczosStepType() == 
            Interface::FITKAbaAbstractStep::MaximumNumberOfBlockLanczosStep::ValueMaximum)
        {
            int LanczosSteps = _stepData->getMaxNumOfBlockLanczosSteps();
            valueLine.append(QString::number(LanczosSteps));
        }
        return true;
    }

    bool FITKAbaqusAdaptorStepFrequency::writeAMS()
    {
        //eigensolver
        titleLine.append("*Frequency, eigensolver=AMS");

        if (_stepData->getNumberOfEigenvaluesRequstedType() ==
            Interface::FITKAbaAbstractStep::NumberOfEigenvaluesRequsted::ValueNumberOfEigen)
        {
            int eigenvalues = _stepData->getNumberOfEigenvaluesRequested();
            valueLine.append(QString::number(eigenvalues));
        }
        valueLine.append(", ");

        if (_stepData->getMinFreqIntrest())
        {
            double minFrequency = _stepData->getMinFreqInterstValue();
            valueLine.append(_writer->double2String(minFrequency, 8, 0));
        }
        valueLine.append(", ");

        if (_stepData->getMaxFreqInterst())
        {
            double maxFrequency = _stepData->getMaxFreqInterstValue();
            valueLine.append(_writer->double2String(maxFrequency, 8, 0));
        }
        valueLine.append(", ");

        //if (_stepData->getFrequencyShift())
        //{
        //    double ShiftValue = _stepData->getFrequencyShiftValue();
        //    valueLine.append(_writer->double2String(ShiftValue, 8, 0));
        //}
        //valueLine.append(", ");
        //
        //if (_stepData->getFrequencyShift())
        //{
        //    int VectorsUsed = _stepData->getVectorsUsedPerIteration();
        //    valueLine.append(QString::number(VectorsUsed));
        //}
        //valueLine.append(", ");

        if (_stepData->getMaxNumberOfIteration())
        {
            int maxIteration = _stepData->getMaxNumberOfIteration();
            valueLine.append(QString::number(maxIteration));
        }
        return true;
    }

    bool FITKAbaqusAdaptorStepFrequency::writeSubspace()
    {
        //eigensolver
        titleLine.append("*Frequency, eigensolver=Lanczos");

        if (_stepData->getNumberOfEigenvaluesRequstedType() == 
            Interface::FITKAbaAbstractStep::NumberOfEigenvaluesRequsted::ValueNumberOfEigen)
        {
            int eigenvalues = _stepData->getNumberOfEigenvaluesRequested();
            valueLine.append(QString::number(eigenvalues));
        }
        valueLine.append(", ");

        if (_stepData->getMaxFreqInterst())
        {
            double maxFrequency = _stepData->getMaxFreqInterstValue();
            valueLine.append(_writer->double2String(maxFrequency, 8, 0));
        }
        valueLine.append(", ");

        if (_stepData->getFrequencyShift())
        {
            double ShiftValue = _stepData->getFrequencyShiftValue();
            valueLine.append(_writer->double2String(ShiftValue, 8, 0));
        }
        valueLine.append(", ");

        if (_stepData->getFrequencyShift())
        {
            int VectorsUsed = _stepData->getVectorsUsedPerIteration();
            valueLine.append(QString::number(VectorsUsed));
        }
        valueLine.append(", ");

        if (_stepData->getMaxNumberOfIteration())
        {
            int maxIteration = _stepData->getMaxNumberOfIteration();
            valueLine.append(QString::number(maxIteration));
        }
        return true;
    }

    bool FITKAbaqusAdaptorStepFrequency::processingLengthAndIsNull(QStringList strList, int index)
    {
        if (strList.size() > index && !strList[index].trimmed().isEmpty())
            return true;
        return false;
    }
}
